

#include "server.h"

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define BUFFSIZE	1024

/*测试多路复用select*/

/*int main(int argc,char **argv)
  {
  server_select_create();

  return 0;
  }
  */

/*功能：监测文件描述符，读数据，存数据
 *参数：sockfd:socket文件描述符
 *返回：错误返回-1
 */

int server_select_create(int	fd)
{
	fd_set 		readset;
	sqlite3         *db;
	int 		sockfd ;
	int 		maxfd = 0;
	int 		clienfd;
	int 		re_val;	
	int 		i ;
	int 		client_length;
	int		array_full = 0;
	struct 		sockaddr_in client_addr;
	int 		fd_array[FDARRAYNUM];//用于比较出最大的文件描述符
	char		receive_buff[BUFFSIZE];
	char		finish[25]="serve receive finish!";
	char            ID[50];
	char            temp[10];
	char            time[20];
	
	sockfd = fd;

	for(i = 0; i<ARRAY_SIZE(fd_array); i++)
	{
		fd_array[i]=-1;
	}
	fd_array[0] = sockfd;


	while(1)
	{
		FD_ZERO(&readset);//清空可读描述集


		for(i=0; i<ARRAY_SIZE(fd_array) ; i++)
		{
			if( fd_array[i] < 0 )
			{
				continue;
			}

			maxfd = fd_array[i]>maxfd ? fd_array[i] : maxfd;
			FD_SET(fd_array[i], &readset);//将文件描述符添加至可读集中
		} 
		re_val = select(maxfd+1,&readset,NULL,NULL,NULL);//使用于非阻塞socket中同时监听多个文件描述符
		if(re_val < 0)
		{
			printf("select error:%s\n",strerror(errno));
			break;
		}
		else if(0 == re_val)
		{
			printf("select get timeout!\n");
			continue;
		}

		//判断是否有新的客户端连接上来
		if ( FD_ISSET(sockfd, &readset) )
		{
			if( (clienfd = accept(sockfd, (struct sockaddr *)&client_addr,&client_length)) < 0)
			{
				printf("accept new client failure: %s\n", strerror(errno));
				continue;
			}

			array_full = 0;

			for(i = 0; i < ARRAY_SIZE(fd_array); i++)
			{
				if( fd_array[i] < 0 )
				{
					printf("accept new client[%d] and add it into array\n", clienfd );
					mylog(__FUNCTION__,__LINE__,INFO,"accept new client[%d] and add it into array\n",clienfd);
					fd_array[i] = clienfd;
					array_full = 1;
					break;
				}
			}

			//判断描述符缓冲区是否已满
			if( !array_full )
			{
				printf("accept new client[%d] but full, so refuse it\n", clienfd);
				close(clienfd);
			}
		}

		//已经连接得客户端有数据到来
		else
		{


			memset(receive_buff,0,sizeof(receive_buff));//清空接收缓冲区

			for(i = 0; i<ARRAY_SIZE(fd_array); i++)
			{
				if( fd_array[i]<0 || !FD_ISSET(fd_array[i], &readset))
				{
					continue;
				}


				if( (re_val = read(fd_array[i], receive_buff, sizeof(receive_buff))) <= 0)
				{
					printf("socket[%d] read failure or get disconncet.\n", fd_array[i]);
					close(fd_array[i]);
					fd_array[i] = -1;
				}
				else
				{
					printf("server read [%d] bytes from clienfd[%d]:%s\n",re_val,fd_array[i],receive_buff);
					mylog(__FUNCTION__,__LINE__,INFO,"server read [%d] bytes from clienfd[%d]:%s\n",re_val,fd_array[i],receive_buff);
				
					//数据解析

					memset(ID,0,sizeof(ID));
					memset(temp,0,sizeof(temp));
					memset(time,0,sizeof(time));

					deal_data(receive_buff,ID,temp,time);

					datbas_open(&db);//打开数据库

					//存入数据库
					datbas_insert(db,ID,temp,time);
					
					datbas_close(db);
					//通知客户端数据接收完成
					if( write(fd_array[i],finish,sizeof(finish)) < 0 )
					{
						printf("socket[%d] write failure: %s\n", fd_array[i], strerror(errno));
						close(fd_array[i]);
						fd_array[i] = -1;
					}
				}
			}
		}


	}

	return -1;
}
